package org.onvivals.app.ai.llm.model.openAI;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.onvivals.app.ai.llm.AbstractLlmService;
import org.onvivals.module.pms.entity.PmsHistory;
import org.onvivals.module.pms.entity.PmsRole;
import org.onvivals.module.pms.entity.vo.MessageVo;
import org.onvivals.module.pms.service.IPmsHistoryService;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * DifyCloudService
 *
 * @author weirdor (179946422@qq.com)
 * @version v1.0.0
 */
public class OpenAICloudService extends AbstractLlmService {

    private static final Logger log = LoggerFactory.getLogger(OpenAICloudService.class);
    private OkHttpClient okHttpClient;

	private JSONObject llmConfig;

	public PmsRole pmsRole;

	public OpenAICloudService(JSONObject llmConfig, PmsRole roles) {
		this.okHttpClient = new OkHttpClient.Builder()
				.connectTimeout(1, TimeUnit.DAYS)
				.readTimeout(1, TimeUnit.DAYS)
				.build();
		this.llmConfig = llmConfig;
		this.pmsRole = roles;
	}

    @Override
    public void chat(String query, String userId, String productId, String deviceNum) {
        chat(query, userId, IdUtil.getSnowflakeNextIdStr(), deviceNum);
    }

    @Override
    public void chat(String query, String conversationId, String deviceNum) {
        sendChatRequest(query, conversationId, deviceNum);
    }

    private void sendChatRequest(String query, String conversationId, String deviceNum) {
		String prompt = pmsRole.getPrompt();
		String model = llmConfig.getStr("model");
		String key = llmConfig.getStr("key");
		String baseUrl =  llmConfig.getStr("base_url");
        IPmsHistoryService pmsHistoryService = SpringUtil.getBean(IPmsHistoryService.class);
        List<PmsHistory> list = pmsHistoryService.list(Wrappers.<PmsHistory>lambdaQuery().eq(PmsHistory::getDeviceId,deviceNum));
		Integer maxMessageCount = pmsRole.getMaxMessageCount();
		log.info("maxMessageCount:{}",maxMessageCount);
        if (list.size() > maxMessageCount.intValue()){
            pmsHistoryService.remove(Wrappers.<PmsHistory>lambdaQuery().eq(PmsHistory::getDeviceId,deviceNum));
            list= new ArrayList<>();
        }
		if (CollUtil.isEmpty(list)){
			PmsHistory pmsHistory = new PmsHistory();
            pmsHistory.setDeviceId(deviceNum);
            pmsHistory.setRole("system");
            pmsHistory.setContent(prompt);
            pmsHistory.insert();
            list.add(pmsHistory);

			PmsHistory pmsHistorys = new PmsHistory();
			pmsHistorys.setDeviceId(deviceNum);
			pmsHistorys.setRole("user");
			pmsHistorys.setContent(query);
			pmsHistorys.insert();
			list.add(pmsHistorys);
		}else {
			PmsHistory pmsHistory = new PmsHistory();
			pmsHistory.setDeviceId(deviceNum);
			pmsHistory.setRole("user");
			pmsHistory.setContent(query);
			pmsHistory.insert();
			list.add(pmsHistory);
		}
		List<MessageVo> messageVoList = BeanUtil.copyToList(list,MessageVo.class);
		messageVoList = messageVoList.parallelStream().filter(x-> StrUtil.isNotEmpty(x.getContent())).collect(Collectors.toUnmodifiableList());
        Map<String, Object> map = MapUtil.newHashMap();
        map.put("messages", messageVoList);
        map.put("model", model);
        map.put("stream", true);
        String requestJson = JSONUtil.toJsonStr(map);
		log.info("请求参数： {}",requestJson);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, requestJson);
        Request request = new Request.Builder()
                .url(baseUrl)
                .addHeader("Authorization", "Bearer " + key)
                .addHeader("Content-Type", "application/json")
                .post(body)
                .build();
        request = request.newBuilder().post(body).build();
		System.out.println(request.body());
        EventSource.Factory factory = EventSources.createFactory(okHttpClient);
        EventSourceListener sourceListener = new OpenAiSSEEventSourceListener(pmsRole, deviceNum, query);
        //创建事件
        factory.newEventSource(request, sourceListener);
    }
}
